﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Subtle.Domain.Services.Interfaces;
using XmlRpcMvc.Common;
using System.Web;
using CookComputing.XmlRpc;
using Subtle.Domain.Services.RssModels;
using Subtle.Data.Configuration;
using NHibernate;
using Subtle.Data.Persistence.Interfaces;
using Subtle.Data.Persistence;
using Subtle.Data.Extensions;

namespace Subtle.Domain.Services
{
	/// <summary>
	/// Meta Weblog
	/// </summary>
	public class MetaWeblog : XmlRpcService, IMetaWeblog
	{
		private IPostService postService;
		private IUserService userService;
		private IEmailService emailService;

		private IRepository repository;

		private ISession session;

		/// <summary>
		/// Initializes a new MetaWeblog API
		/// </summary>
		public MetaWeblog()
		{
			ISessionFactory sessionFactory = SessionFactoryBuilder.SessionFactory;
			session = sessionFactory.OpenSession();

			repository = new Repository(session);

			postService = new PostService(repository);
			emailService = new EmailService();
			userService = new UserService(repository, emailService);
		}

		/// <summary>
		/// Add Post
		/// </summary>
		/// <param name="blogid"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <param name="post"></param>
		/// <param name="publish"></param>
		/// <returns></returns>
		string IMetaWeblog.AddPost(string blogid, string username, string password, Post post, bool publish)
		{
			var user = userService.GetUser(username, password);
			if (user == null) //User is not valid
				return null;

			//get the category
			var category = postService.GetCategory(post.categories.FirstOrDefault());
			if(category == null)
			{
				postService.CreateCategory(post.categories.FirstOrDefault());
				category = postService.GetCategory(post.categories.FirstOrDefault());
			}

			//get the tag
			var tag = postService.GetTag(post.categories.FirstOrDefault());
			if (tag == null)
			{
				postService.CreateTag(post.categories.FirstOrDefault());
				tag = postService.GetTag(post.categories.FirstOrDefault());
			}

			//Save the post
			var newPost = new Subtle.Domain.Models.Post
			{
				Body = post.description,
				Title = post.title,
				SanitizedTitle = post.title.Sanitize(),
				User = user,
				Active = publish,
				Category = category,
				Tags = new Subtle.Domain.Models.Tag[]{tag},
				DateCreated = post.dateCreated.HasValue ? post.dateCreated.Value : DateTime.Now,
				PublishDate = DateTime.Now
			};
			postService.SavePost(newPost);
			return newPost.ID.ToString();
		}

		/// <summary>
		/// Update Post
		/// </summary>
		/// <param name="postid"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <param name="post"></param>
		/// <param name="publish"></param>
		/// <returns></returns>
		bool IMetaWeblog.UpdatePost(string postid, string username, string password, Post post, bool publish)
		{
			var user = userService.GetUser(username, password);
			if (user == null) //User is not valid
				return false;

			//ToDo : Add More Updates
			var postToUpdate = postService.GetPost(int.Parse(postid));
			postToUpdate.Body = post.description;
			postService.SavePost(postToUpdate);
			return true;
		}

		/// <summary>
		/// Get Post
		/// </summary>
		/// <param name="postid"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <returns></returns>
		Post IMetaWeblog.GetPost(string postid, string username, string password)
		{
			var user = userService.GetUser(username, password);
			if (user == null) //User is not valid
				return new Post{};

			var postToGet = postService.GetPost(int.Parse(postid));

			//ToDo : Flesh out a bit more
			return new Post
			{
				dateCreated = postToGet.DateCreated,
				description = postToGet.Body,
				postid = postToGet.ID.ToString(),
				title = postToGet.Title,
				userid = postToGet.User.ID.ToString(),
				categories = new string[]{postToGet.Category.Description}
			};
		}

		/// <summary>
		/// Get Categories
		/// </summary>
		/// <param name="blogid"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <returns></returns>
		CategoryInfo[] IMetaWeblog.GetCategories(string blogid, string username, string password)
		{
			var user = userService.GetUser(username, password);
			if (user == null) //User is not valid
				return null;

			var categoryInfos = from category in postService.GetCategories()
								select new CategoryInfo{
									categoryid = category.ID.ToString(),
									description = category.Description,
									title = category.Description,
									htmlUrl = category.Description,
									rssUrl = category.Description
								};
			return categoryInfos.ToArray();
		}

		/// <summary>
		/// Get Recent Posts
		/// </summary>
		/// <param name="blogid"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <param name="numberOfPosts"></param>
		/// <returns></returns>
		Post[] IMetaWeblog.GetRecentPosts(string blogid, string username, string password, int numberOfPosts)
		{
			return new Post[]
			{
				new Post(){
				}
			};
		}

		/// <summary>
		/// Get New Media Object
		/// </summary>
		/// <param name="blogid"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <param name="mediaObject"></param>
		/// <returns></returns>
		MediaObjectInfo IMetaWeblog.NewMediaObject(string blogid, string username, string password, MediaObject mediaObject)
		{
			return new MediaObjectInfo
			{
			};
		}

		/// <summary>
		/// New Category
		/// </summary>
		/// <param name="blogid"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <param name="category"></param>
		/// <returns></returns>
		int IMetaWeblog.newCategory(string blogid, string username, string password, WordpressCategory category)
		{
			var user = userService.GetUser(username, password);
			if (user == null) //User is not valid
				return -1;

			var categoryQuery = postService.GetCategory(category.name);
			return postService.CreateCategory(category.name) ? 1 : -1;
		}

		/// <summary>
		/// Delete Post
		/// </summary>
		/// <param name="key"></param>
		/// <param name="postid"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <param name="publish"></param>
		/// <returns></returns>
		bool IMetaWeblog.DeletePost(string key, string postid, string username, string password, bool publish)
		{
			return true;
		}

		/// <summary>
		/// Get Users Blogs
		/// </summary>
		/// <param name="key"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <returns></returns>
		BlogInfo[] IMetaWeblog.GetUsersBlogs(string key, string username, string password)
		{
			var user = userService.GetUser(username, password);
			if (user == null) //User is not valid
				return null;

			//ToDo : Configify
			return new BlogInfo[]{new BlogInfo
			{
				blogid = "0",
				blogName = "PieterG.com",
				url = "http://www.pieterg.com"
			}};
		}

		/// <summary>
		/// Get User Information
		/// </summary>
		/// <param name="key"></param>
		/// <param name="username"></param>
		/// <param name="password"></param>
		/// <returns></returns>
		UserInfo IMetaWeblog.GetUserInfo(string key, string username, string password)
		{
			var user = userService.GetUser(username, password);
			if (user == null) //User is not valid
			{
				return new UserInfo
				{
					//ToDo : What to do here
				};
			}
			return new UserInfo
			{
				email = user.Username,
				firstname = user.Username,
				userid = user.ID.ToString()
			};
		}
	}
}
